home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / gip_02.zip / GIP.ASM < prev    next >
Assembly Source File  |  1994-12-16  |  35KB  |  1,124 lines

  1. ; Copyright (c) 1991-1994, John David Rohner.  All rights reserved.
  2.  
  3. ;
  4. ; These are the assembly graphics routines I created for the GIP stuff.
  5. ;
  6. ; If anyone can improve upon them, please do and send me the changes.
  7. ;
  8. ; I do not release these routines to the public domain.  However, they are
  9. ; free without obligation or credit for applications using them to implement
  10. ; the GIP standard.
  11. ;
  12.  
  13. .286
  14. .Model Medium, Basic
  15. .Code
  16.  
  17. extrn   StringAddress: proc
  18. extrn   CursorOff: proc
  19.  
  20. ;
  21. ; There is order to this madness!  The order exists around the fact that we
  22. ; support 3 types of display: 640x480x16 first, 320x200x256 second, and
  23. ; everything else (via BIOS calls) last.
  24. ;
  25. ; Of all the code here, the only part that matters is the actual pixel
  26. ; drawing loops.  In all the routines, these have been pulled out into
  27. ; subroutines to maximize their speed (each display mode is quite unique).
  28. ; Every cycle saved in these loops will have noticable improvement (depending
  29. ; on how many pixels we're drawing), whereas the code outside these loops
  30. ; doesn't really affect speed at all.
  31. ;
  32.  
  33.  
  34. ;
  35. ; Change to a screen mode.
  36. ;
  37. ; GSetMode (BYVAL ModeToUse%, BYVAL 640x480x256Mode%,  BYVAL 800x600x256Mode%)
  38. ;
  39. ; upon entry: 0 = 80x25x16 ansi mode
  40. ;             1 = 320x200x4 CGA mode (for testing only)
  41. ;             2 = 640x480x16 VGA mode
  42. ;             3 = 320x200x256 VGA mode
  43. ;             4 = 640x480x256 SVGA mode
  44. ;             5 = 800x600x256 SVGA mode
  45. ;
  46.  
  47.             PUBLIC  GSetMode          ;Make this routine available to LINK.
  48.  
  49. GSetMode    proc    far               ;Beginning of routine.
  50.  
  51.             push    bp
  52.             mov     bp,sp
  53.  
  54.             mov     al,[bp + 0AH]     ;Get the mode to use.
  55.             mov     GModeInUse,al
  56.             mov     GScrMem,0A000H
  57.  
  58.         R0: cmp     al,1              ;Check to see if graphics mode 1,
  59.             jne     RN1
  60.             mov     al,4              ;which is 320x200x4 CGA
  61.             mov     GScrMem,0B800H
  62.             jmp     D1
  63.  
  64.        RN1: cmp     al,-1             ;Check to see if graphics mode 1,
  65.             jne     R2
  66.             mov     al,4              ;which is 320x200x4 CGA
  67.             mov     GScrMem,0B800H
  68.             jmp     D1
  69.  
  70.         R2: cmp     al,2              ;Check to see if graphics mode 18,
  71.             jne     RN2               ;which is 640x480x16 VGA
  72.             mov     al,12H
  73.             jmp     D1
  74.  
  75.        RN2: cmp     al,-2             ;Check to see if graphics mode 18,
  76.             jne     R3                ;which is 640x480x16 VGA
  77.             mov     al,12H
  78.             jmp     D1
  79.  
  80.         R3: cmp     al,3              ;Check to see if graphics mode 19,
  81.             jne     RN3               ;which is 320x200x256 VGA
  82.             mov     al,13H
  83.             jmp     D1
  84.  
  85.        RN3: cmp     al,-3             ;Check to see if graphics mode 19,
  86.             jne     R4                ;which is 320x200x256 VGA
  87.             mov     al,13H
  88.             jmp     D1
  89.  
  90.         R4: cmp     al,4              ;Check to see if 640x480x256
  91.             jne     R5
  92.             mov     al,[bp + 08]
  93.             jmp     D1
  94.  
  95.         R5: cmp     al,5              ;Check to see if 800x600x256
  96.             jne     D2
  97.             mov     al,[bp + 06]
  98.             jmp     D1
  99.  
  100.  
  101.         D2: cmp     al,50
  102.             jne     D3
  103.             mov     GModeInUse,0
  104.             mov     ax,3
  105.             int     10H
  106.             mov     ax,1112h
  107.             xor     bl,bl
  108.             int     10H
  109.             jmp     Done
  110.  
  111.         D3: mov     al,3              ;Else, standard 80x25x16 ANSI mode.
  112.  
  113.                 mov     ax,3
  114.                 int     10h                     ; Video display   ah=functn 00h
  115.                                                 ;  set display mode in al
  116.                 mov     ax,1104h
  117.                 xor     bl,bl                   ; Zero register
  118.                 int     10h                     ; Video display   ah=functn 11h
  119.                                                 ;  load 8x16 font, bl=block
  120.                 mov     ax,1103h
  121.                 xor     bl,bl                   ; Zero register
  122.                 int     10h                     ; Video display   ah=functn 11h
  123.                                                 ;  set active font block bl
  124. ;call CursorOff
  125. jmp Done
  126.  
  127.  
  128.         D1: xor     ah,ah
  129.             int     10H
  130.  
  131.       Done: 
  132.  
  133. call CursorOff
  134.  
  135. pop     bp
  136.             ret     6                 ;Pop-return past our input parameters.
  137.  
  138. GSetMode    endp                      ;End of routine.
  139.  
  140.  
  141. ;
  142. ; Display text in a given color at given coordinates.
  143. ;
  144. ; ColorText (BYVAL Horiz%, BYVAL Vert%, BYVAL Color%, BYVAL CharToDisp%)
  145. ;
  146. ; Temporarily using DOS 8x8 font until I can figure out the TrueType font
  147. ; file structure and implement those fonts.
  148. ;
  149.  
  150.             PUBLIC  ColorText         ;Make this routine available to LINK.
  151.  
  152. ColorText   proc    far               ;Beginning of routine.
  153.  
  154.             push    bp
  155.             mov     bp,sp
  156.  
  157.             mov     al,[bp + 06]      ;Character to display
  158.             cmp     al,32             ;Nothing to do if a space.
  159.             je      Done
  160.  
  161.             push    ds
  162.  
  163.             mov     es,GScrMem
  164.             xor     ah,ah
  165.             shl     ax,3              ;8 pixels high.
  166.             mov     si,0FA6EH         ;Start of DOS font table.
  167.             add     si,ax
  168.             push    0F000H            ;Segment of the font table.
  169.             pop     ds
  170.  
  171.             mov     dx,[bp + 0AH]     ;Vertical start.
  172.             mov     bx,8              ;8 pixels high.
  173.             mov     cx,[bp + 0CH]     ;Horizontal start.
  174.  
  175.             cmp     GModeInUse,2      ;640x480x16 VGA
  176.             jne     R1
  177.             call    ColorText1
  178.             jmp     D1
  179.         R1: cmp     GModeInUse,3      ;320x200x256 VGA
  180.             jne     R2
  181.             call    ColorText2
  182.             jmp     D1
  183.         R2: call    ColorText3
  184.  
  185.         D1: pop     ds
  186.       Done: pop     bp
  187.             ret     8                 ;Pop-return past our input parameters.
  188.  
  189. ColorText   endp                      ;End of routine.
  190. ;
  191. ColorText1  proc    near              ;Beginning of routine.
  192.             mov     di,dx          ;
  193.             shl     di,2           ;
  194.             add     di,dx          ;
  195.             shl     di,4           ;DI = DX * 80
  196.             mov     al,[bp + 08]      ;Color to use.
  197.         R1: mov     dx,8           ;8 pixels wide.
  198.             mov     ah,ds:[si]
  199.             inc     si
  200.         R2: shl     ah,1              ;Pixel value -> CF.
  201.             jnc     R3
  202.             pusha
  203.             push    cx
  204.             shr     cx,3
  205.             add     di,cx
  206.             pop     cx
  207.             and     cx,7
  208.             mov     ch,80H
  209.             mov     dx,03CEH
  210.             push    ax
  211.             mov     ax,0205H
  212.             out     dx,ax             ;vga graphics index
  213.             shr     ch,cl
  214.             mov     ah,ch
  215.             mov     al,8
  216.             out     dx,ax
  217.             pop     ax
  218.             mov     ah,es:[di]
  219.             stosb                     ;(ES:DI) <- al
  220.             popa
  221.         R3: inc     cx                ;Move right one pixel.
  222.             dec     dx
  223.             jnz     R2
  224.             add     di,80             ;Move down one pixel.
  225.             sub     cx,8
  226.             dec     bx
  227.             jnz     R1
  228.             ret
  229. ColorText1  endp                      ;End of routine.
  230. ;
  231. ColorText2  proc    near              ;Beginning of routine.
  232.             mov     di,dx          ;duplicate starting vert to DI
  233.             shl     di,2           ;
  234.             add     di,dx          ;
  235.             shl     di,6           ;DI = Line * 320
  236.             add     di,cx          ;                + our horizontal start.
  237.             mov     ah,[bp + 08]      ;Color to use.
  238.         R1: mov     cx,8               ;8 pixels wide.
  239.             lodsb                     ;AL <- (DS:SI)
  240.         R2: shl     al,1              ;Pixel value -> CF.
  241.             jnc     R3
  242.             mov     es:[di],ah
  243.         R3: inc     di                ;Move right one pixel.
  244.             loop    R2
  245.             add     di,312             ;Move down one pixel. (320 - 8)
  246.             dec     bx
  247.             jnz     R1
  248.             ret
  249. ColorText2  endp                      ;End of routine.
  250. ;
  251. ColorText3  proc    near              ;Beginning of routine.
  252.             ;
  253.             ; Bios wants: CX = horizontal position
  254.             ;             DX = vertical position
  255.             ;             AL = color
  256.             ; BH = video page zero, which we get with MOV BX,8 earlier.
  257.             ;
  258.             mov     al,[bp + 08]      ;Color to use.
  259.         R1: mov     di,8              ;8 pixels wide.
  260.             mov     ah,ds:[si]
  261.             inc     si
  262.         R2: shl     ah,1              ;Pixel value -> CF.
  263.             jnc     R3
  264.             pusha
  265.             mov     ah,0CH            ;BIOS: draw pixel
  266.             int     10H               ;changes ax,si,di
  267.             popa
  268.         R3: inc     cx                ;Move right one pixel.
  269.             dec     di
  270.             jnz     R2
  271.             inc     dx                ;Move down one pixel.
  272.             sub     cx,8
  273.             dec     bx
  274.             jnz     R1
  275.             ret
  276. ColorText3  endp                      ;End of routine.
  277.  
  278.  
  279. ;
  280. ; Draw-A-Multiple-Color-Solid-Horizontal-Line-Fast
  281. ;
  282. ; DAMCSHLF (BYVAL Horiz%, BYVAL Vert%, Colors$, LineWidth, BitsPerColor)
  283. ;
  284. ; BitsPerColor = 4 or 8 for color bits within the string.
  285. ;
  286. ; To draw lines for stuff like icon's and BMP's.  You should call this
  287. ; routine with Vert% pointing to the end of the image.  It is the job of
  288. ; the calling routine to update Vert%.
  289. ;
  290. ; This doesn't handle non-even line lengths with 4 bits (29, 31, 319, etc.).
  291. ; However I'm not so sure such images are possible, we'll wait and see.
  292. ;
  293.  
  294.             PUBLIC  DAMCSHLF          ;Make this routine available to LINK.
  295.  
  296. DAMCSHLF    proc    far               ;Beginning of routine.
  297.  
  298.             push    bp
  299.             mov     bp,sp
  300.  
  301.             push    [bp + 0AH]
  302.             call    StringAddress
  303.             jcxz    Done
  304.             push    ds
  305.             mov     ds,dx
  306.             xchg    si,ax              ;DS:SI holds our colors.
  307.             ;
  308.             mov     es,GScrMem
  309.             cld
  310.             mov     dx,[bp + 0CH]      ;Vert%
  311.             mov     bx,[bp + 06]       ;Bits-per-color
  312.             cmp     bx,8
  313.             je      R8
  314.             ;
  315.             ; Display the 4 bit 16 color lines.
  316.             ;
  317.             cmp     GModeInUse,2      ;640x480x16 VGA
  318.             jne     R1
  319.             call    DAMCSHLF1
  320.             jmp     D1
  321.         R1: cmp     GModeInUse,3      ;320x200x256 VGA
  322.             jne     R2
  323.             call    DAMCSHLF2
  324.             jmp     D1
  325.         R2: call    DAMCSHLF3
  326.             jmp     D1
  327.             ;
  328.             ; Display theh 8 bit 256 color lines.
  329.             ;
  330.         R8: cmp     GModeInUse,2      ;640x480x16 VGA
  331.             jne     R3
  332.             call    DAMCSHLF4
  333.             jmp     D1
  334.         R3: cmp     GModeInUse,3      ;320x200x256 VGA
  335.             jne     R4
  336.             call    DAMCSHLF5
  337.             jmp     D1
  338.         R4: call    DAMCSHLF6
  339.             jmp     D1
  340.  
  341.         D1: pop     ds
  342.       Done: pop     bp
  343.             ret     0AH                 ;Pop-return past our input parameter.
  344.  
  345. DAMCSHLF    endp                      ;End of routine.
  346. ;
  347. DAMCSHLF1   proc    near              ;Beginning of routine.
  348.             mov     di,dx          ;Convert DI to memory coordinates.
  349.             shl     di,2           ;
  350.             add     di,dx          ;
  351.             shl     di,4           ;DI = DX * 80
  352. x0:
  353.             mov     bx,[bp + 0EH]     ;StartH
  354.             push cx
  355.             mov     cx,[bp + 08]
  356. x1:
  357.             lodsb
  358.             mov ah,al
  359.             shr al,4
  360.             pusha
  361.             mov     cx,bx
  362.             shr     bx,3
  363.             add     di,bx
  364.             mov     bl,al
  365.             mov     dx,03CEH
  366.             mov     ax,0205H
  367.             out     dx,ax             ;vga graphics index
  368.             and     cx,7
  369.             mov     ch,128            ;10000000 rotating bank selector.
  370.             shr     ch,cl
  371.             mov     ah,ch
  372.             mov     al,8
  373.             out     dx,ax
  374.             mov     ah,es:[di]
  375.             mov     al,bl
  376.             stosb                     ;(ES:DI) <- al
  377.             popa
  378.             inc bx
  379.             and ah,15
  380.             pusha
  381.             mov     cx,bx
  382.             shr     bx,3
  383.             add     di,bx
  384.             mov     bl,ah
  385.             mov     dx,03CEH
  386.             mov     ax,0205H
  387.             out     dx,ax             ;vga graphics index
  388.             and     cx,7
  389.             mov     ch,128            ;10000000 rotating bank selector.
  390.             shr     ch,cl
  391.             mov     ah,ch
  392.             mov     al,8
  393.             out     dx,ax
  394.             mov     ah,es:[di]
  395.             mov     al,bl
  396.             stosb                     ;(ES:DI) <- al
  397.             popa
  398.             inc bx
  399.             loop x1
  400.             sub     di,80
  401.             pop cx
  402.             sub cx,[bp + 08]
  403.             inc cx
  404.             loop x0
  405.             ret
  406. DAMCSHLF1   endp                      ;End of routine.
  407. ;
  408. DAMCSHLF2   proc    near              ;Beginning of routine.
  409.             mov     bx,[bp + 0EH]     ;StartH
  410.             mov     di,dx          ;Convert screen coor to memory coor.
  411.             shl     di,2           ;
  412.             add     di,dx          ;
  413.             shl     di,6           ;AX = Line * 320
  414.             add     di,bx          ;                + our horizontal start.
  415. x10:
  416.             mov     bx,[bp + 0EH]     ;StartH
  417.             push cx
  418.             mov     cx,[bp + 08]
  419. x11:
  420.             lodsb
  421.             mov ah,al
  422.             shr al,4
  423.             pusha
  424. ;            mov     di,dx          ;duplicate starting vert to DI
  425. ;            shl     di,2           ;
  426. ;            add     di,dx          ;
  427. ;            shl     di,6           ;AX = Line * 320
  428. ;            add     di,bx          ;                + our horizontal start.
  429.             stosb
  430.             popa
  431. ;            inc bx
  432. inc di
  433.             mov al,ah
  434.             and al,15
  435.             pusha
  436. ;            mov     di,dx          ;duplicate starting vert to DI
  437. ;            shl     di,2           ;
  438. ;            add     di,dx          ;
  439. ;            shl     di,6           ;AX = Line * 320
  440. ;            add     di,bx          ;                + our horizontal start.
  441.             stosb
  442.             popa
  443. ;            inc bx
  444. inc di
  445.             loop x11
  446. ;            dec dx
  447. sub di,320
  448. sub di,bx
  449.             pop cx
  450.             sub cx,[bp + 08]
  451.             inc cx
  452.             loop x10
  453.             ret
  454. DAMCSHLF2   endp                      ;End of routine.
  455. ;
  456. DAMCSHLF3   proc    near              ;Beginning of routine.
  457. ;BIOS output
  458. x40:
  459.             mov     bx,[bp + 0EH]     ;StartH
  460.             push cx
  461.             mov     cx,[bp + 08]
  462. x41:
  463.             lodsb
  464.             mov ah,al
  465.             shr al,4
  466.         R4: pusha
  467.             mov     ah,0CH            ;BIOS: draw pixel
  468.             mov     cx,bx             ;Horiz -> CX.
  469.             xor     bh,bh             ;video page 0.
  470.             int     10H               ;changes ax,si,di
  471.             popa
  472.             inc bx
  473.             mov al,ah
  474.             and al,15
  475.             pusha
  476.             mov     ah,0CH            ;BIOS: draw pixel
  477.             mov     cx,bx             ;Horiz -> CX.
  478.             xor     bh,bh             ;video page 0.
  479.             int     10H               ;changes ax,si,di
  480.             popa
  481.             inc bx
  482.             loop x41
  483.             dec dx
  484.             pop cx
  485.             sub cx,[bp + 08]
  486.             inc cx
  487.             loop x40
  488.             ret
  489. DAMCSHLF3   endp                      ;End of routine.
  490. ;
  491. DAMCSHLF4   proc    near              ;Beginning of routine.
  492. d256c:
  493.             mov     bx,[bp + 0EH]     ;StartH
  494.             push cx
  495.             mov     cx,[bp + 08]
  496.    x2:
  497.             lodsb
  498.             pusha
  499.             mov     di,dx          ;
  500.             shl     di,2           ;
  501.             add     di,dx          ;
  502.             shl     di,4           ;DI = DX * 80
  503.             mov     cx,bx
  504.             shr     bx,3
  505.             add     di,bx
  506.  
  507.             mov     bl,al
  508.             mov     dx,03CEH
  509.             mov     ax,0205H
  510.             out     dx,ax             ;vga graphics index
  511.  
  512.             and     cx,7
  513.             mov     ch,128            ;10000000 rotating bank selector.
  514.             shr     ch,cl
  515.             mov     ah,ch
  516.             mov     al,8
  517.             out     dx,ax
  518.             mov     ah,es:[di]
  519.             mov     al,bl
  520.             stosb                     ;(ES:DI) <- al
  521.             popa
  522.             inc bx
  523.             loop x2
  524.             dec dx
  525.             pop cx
  526.             sub cx,[bp + 08]
  527.             inc cx
  528.             loop d256c
  529.             ret
  530. DAMCSHLF4   endp                      ;End of routine.
  531. ;
  532. DAMCSHLF5   proc    near              ;Beginning of routine.
  533. d256c:
  534.             mov     bx,[bp + 0EH]     ;StartH
  535.             push cx
  536.             mov     cx,[bp + 08]
  537. x2:
  538.             lodsb
  539.             pusha
  540.             mov     di,dx          ;duplicate starting vert to DI
  541.             shl     di,2           ;
  542.             add     di,dx          ;
  543.             shl     di,6           ;AX = Line * 320
  544.             add     di,bx          ;                + our horizontal start.
  545.             stosb
  546.             popa
  547.             inc bx
  548.             loop x2
  549.             dec dx
  550.             pop cx
  551.             sub cx,[bp + 08]
  552.             inc cx
  553.             loop d256c
  554.             ret
  555. DAMCSHLF5   endp                      ;End of routine.
  556. ;
  557. DAMCSHLF6   proc    near              ;Beginning of routine.
  558. d256c:
  559.             mov     bx,[bp + 0EH]     ;StartH
  560.             push cx
  561.             mov     cx,[bp + 08]
  562. x2:
  563.             lodsb
  564.             pusha
  565.             mov     ah,0CH            ;BIOS: draw pixel
  566.             mov     cx,bx             ;Horiz -> CX.
  567.             xor     bh,bh             ;video page 0.
  568.             int     10H               ;changes ax,si,di
  569.             popa
  570.             inc bx
  571.             loop x2
  572.             dec dx
  573.             pop cx
  574.             sub cx,[bp + 08]
  575.             inc cx
  576.             loop d256c
  577.             ret
  578. DAMCSHLF6   endp                      ;End of routine.
  579.  
  580.  
  581. ;
  582. ; Draw a pixel in a given color at given coordinates.
  583. ;
  584. ; GPixel (BYVAL Horiz%, BYVAL Vert%, BYVAL Color%)
  585. ;
  586.  
  587.             PUBLIC  GPixel            ;Make this routine available to LINK.
  588.  
  589. GPixel      proc    far               ;Beginning of routine.
  590.  
  591.             push    bp
  592.             mov     bp,sp
  593.  
  594.             mov     es,GScrMem
  595.             mov     bl,[bp + 06]      ;Pixel's color.
  596.             mov     dx,[bp + 08]      ;vertical position.
  597.             mov     cx,[bp + 0AH]     ;horizontal position.
  598.             call    GPixel2
  599.  
  600.             pop     bp
  601.             ret     6                 ;Pop-return past our input parameter.
  602.  
  603. GPixel      endp                      ;End of routine.
  604. ;
  605. ; Draw a pixel.
  606. ;
  607. ; bl = pixel's color
  608. ; cx = horizontal position
  609. ; dx = vertical position
  610. ;
  611. ; changes: nothing
  612. ;
  613. ; A good general routine to use internally for other routines as well while
  614. ; experimenting.
  615. ;
  616. GPixel2     proc    near              ;Beginning of routine.
  617.  
  618.             pusha
  619.             mov     al,bl
  620.             cmp     GModeInUse,2      ;640x480x16 VGA
  621.             jne     R1
  622.             ;
  623.             mov     di,dx          ;
  624.             shl     di,2           ;
  625.             add     di,dx          ;
  626.             shl     di,4           ;DI = DX * 80
  627.             ;
  628.             push    cx
  629.             shr     cx,3
  630.             add     di,cx
  631.             pop     cx
  632.             and     cx,7
  633.             mov     ch,80H
  634.             ;
  635.             push    ax
  636.             mov     dx,03CEH
  637.             mov     ax,0205H
  638.             out     dx,ax             ;vga graphics index
  639.             ;
  640.             shr     ch,cl
  641.             mov     ah,ch
  642.             mov     al,8
  643.             out     dx,ax
  644.             pop     ax
  645.             mov     ah,es:[di]
  646.             stosb                     ;(ES:DI) <- al
  647.             ;
  648.             popa
  649.             ret
  650.  
  651.         R1: cmp     GModeInUse,3      ;320x200x256 VGA
  652.             jne     R4
  653.             ;
  654.             ; Draw a 320x200x256 VGA pixel.
  655.             ;
  656.             mov     di,dx          ;duplicate starting vert to DI
  657.             shl     di,2           ;
  658.             add     di,dx          ;
  659.             shl     di,6           ;DI = Line * 320
  660.             add     di,cx          ;                + our horizontal start.
  661.             stosb
  662.             popa
  663.             ret
  664.  
  665.         R4: mov     ah,0CH            ;BIOS: draw pixel
  666.             xor     bh,bh             ;video page 0.
  667.             int     10H               ;changes ax,si,di
  668.             popa
  669.             ret
  670.  
  671. GPixel2     endp                      ;End of routine.
  672.  
  673.  
  674. ;
  675. ; Draw a line.  Pretty general routine that calls a bunch of faster line
  676. ; drawing routines.  Only draws in one color.
  677. ;
  678. ; GLine (BYVAL CurrentH%, BYVAL CurrentV%, BYVAL TillH%, BYVAL TillV%, BYVAL Colr%, BYVAL GDither%)
  679. ;
  680. ;
  681.  
  682.             PUBLIC  GLine             ;Make this routine available to LINK.
  683.  
  684. GLine       proc    far               ;Beginning of routine.
  685.  
  686.             push    bp
  687.             mov     bp,sp
  688.  
  689.             mov     es,GScrMem        ;Point ES to the screen.
  690.             cld
  691.             ;
  692.             mov     ax,[bp + 06]      ;Line pattern to use.
  693.             mov     bl,[bp + 08]      ;Line color.
  694.             mov     cx,[bp + 10H]     ;CurrentH
  695.             mov     dx,[bp + 0EH]     ;CurrentV
  696.             mov     di,[bp + 0CH]     ;TillH
  697.             mov     si,[bp + 0AH]     ;TillV
  698.             ;
  699.             ; We can only do this less-than adjust with one of the coordinates.
  700.             ; So we use Horizontal for faster filled box draws.
  701.             ;
  702.             cmp     cx,di
  703.             jle     R1
  704.             xchg    cx,di               ;Now CX always <= DI
  705. xchg dx,si
  706.             ;
  707.         R1: cmp     dx,si
  708.             jne     R3                  ;Not a horizontal line.
  709.             ;
  710.             cmp     ax,-1
  711.             jne     R2                  ;Not a solid horizontal line.
  712.             ;
  713.             ; Draw the solid horizontal line.
  714.             ;
  715.             cmp     GModeInUse,2      ;640x480x16 VGA
  716.             jne     H1
  717.             call    DASCSHLF1
  718.             jmp     Done
  719.         H1: cmp     GModeInUse,3      ;320x200x256 VGA
  720.             jne     H2
  721.             call    DASCSHLF2
  722.             jmp     Done
  723.         H2: call    DASCSHLF3
  724.             jmp     Done
  725.             ;
  726.         R2: call    DL2                 ;Draw a horizontal line with pattern.
  727.             jmp     Done
  728.             ;
  729.         R3: ;cmp     ax,-1
  730.             ;jne     R4                  ;Not a solid line.
  731.             ;call    DASCSLF             ;Draw the solid line.
  732.             ;jmp     Done
  733.         R4: call    DrawLine            ;Draw a line with pattern.
  734.  
  735.       Done: pop     bp
  736.             ret     0CH               ;Pop-return past our input parameter.
  737.  
  738. GLine       endp                      ;End of routine.
  739. ;
  740. ;Draw-A-Single-Color-Solid-Horizontal-Line-Fast
  741. ;
  742. ;Input:
  743. ;  bl  color to use
  744. ;  cx  starting horizontal coordinate (always less than or equal to di)
  745. ;  dx  starting vertical coordinate 
  746. ;  di  ending horizontal coordinate
  747. ;  assumes a RET after this call, so we don't care what we destory.
  748. ;
  749. DASCSHLF1   proc    near              ;Beginning of routine.
  750.             mov     si,di
  751.             sub     si,cx
  752.             inc     si
  753.  
  754.             mov     di,dx          ;
  755.             shl     di,2           ;
  756.             add     di,dx          ;
  757.             shl     di,4           ;DI = DX * 80
  758.             push    cx
  759.             shr     cx,3
  760.             add     di,cx
  761.  
  762.             pop     cx
  763.             and     cx,7
  764.             mov     ch,128            ;10000000 bitmask
  765.             shr     ch,cl
  766.             mov     dx,03CEH
  767.  
  768.             mov bh,ch
  769.             mov cx,si
  770. xx7:
  771.             mov     ax,0205H
  772.             out     dx,ax             ;vga graphics index
  773.  
  774.             mov     ah,bh
  775.             mov     al,8
  776.             out     dx,ax
  777.             mov     ah,es:[di]
  778.             mov     al,bl
  779.             stosb                     ;(ES:DI) <- al
  780.             ror bh,1
  781.             cmp bh,128
  782.             je xx8
  783.             dec di
  784.        xx8: loop xx7
  785.             ret
  786. DASCSHLF1   endp                      ;End of routine.
  787. DASCSHLF2   proc    near              ;Beginning of routine.
  788.             ;
  789.             ; 320x200x256 VGA solid line.  About as fast as possible.
  790.             ;
  791.             sub     di,cx
  792.             xchg    cx,di
  793.             inc     cx
  794.             mov     al,bl
  795.             mov     ah,al
  796.             mov     bx,di          ;starting horiz now in BX
  797.             mov     di,dx          ;duplicate starting vert to DI
  798.             shl     di,2           ;
  799.             add     di,dx          ;
  800.             shl     di,6           ;DI = Line * 320
  801.             add     di,bx          ;                + our horizontal start.
  802.             shr     cx,1
  803.             rep     stosw
  804.             jnc     R33
  805.             stosb
  806.        R33: ret
  807. DASCSHLF2   endp                      ;End of routine.
  808. DASCSHLF3   proc    near              ;Beginning of routine.
  809.             ; Bios wants: CX = horizontal position
  810.             ;             DX = vertical position
  811.             ;             AL = color
  812.             ;
  813.             sub     di,cx
  814.             xchg    cx,di
  815.             inc     cx
  816.             mov     ah,0CH            ;BIOS: draw pixel
  817.             mov     al,bl
  818.             xor     bh,bh             ;video page 0.
  819.        RBB: pusha
  820.             mov     cx,di
  821.             int     10H               ;changes ax,si,di
  822.             popa
  823.             inc     di
  824.             loop    RBB
  825.             ret
  826. DASCSHLF3   endp                      ;End of routine.
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833. DL2    proc    near              ;Beginning of routine.
  834.             ;
  835.             ; This does a quicker draw for stuff for which there are no
  836.             ; slopes, like filled rectangles.  This actually produces no
  837.             ; noticable speed change--any speed improvement has to come from
  838.             ; GPixel2.
  839.             ;
  840.             mov     DPattern2,ax
  841.             rol     DPattern2,1
  842.         a1: ror     DPattern2,1          ;adjust the pattern.
  843.             jnc     a3                  ;don't draw if no need to.
  844.             call    GPixel2
  845.         a3: inc     cx
  846.             cmp     cx,di
  847.             jle     a1
  848.             ret
  849. DPattern2   DW   0
  850. DL2       endp                      ;End of routine.
  851.  
  852.  
  853. DrawLine    proc    near               ;Beginning of routine.
  854.  
  855.             mov     DPattern,ax
  856.             rol     DPattern,1
  857.  
  858.             mov     SlopeV,1
  859.  
  860.             sub     si,dx
  861.             cmp     si,0
  862.             jge     S1
  863.             neg     si
  864.             mov     SlopeV,-1
  865.  
  866.         S1: sub     di,cx
  867.  
  868.         S2: cmp     di,si
  869.             jle     S3
  870.  
  871. ;
  872. ; Plot the line.
  873. ;
  874.  
  875.            mov     ax,di
  876.            shr     ax,1
  877.            mov     unk1,ax           ;unk1 = DI \ 2     growth rate.
  878.            mov     Counter,di
  879.            ror     DPattern,1
  880.            jnc     z1
  881.            call    GPixel2    ;no reason to expand this.
  882. z1:         cmp     di,0
  883.            je      Done
  884.         R1: inc     cx
  885.             add     unk1,si
  886.             cmp     unk1,di
  887.             jle     R2
  888.             sub     unk1,di
  889.             add     dx,SlopeV
  890.         R2: ror     DPattern,1     ;horribly slow! use a register!
  891.             jnc     z2
  892.             call    GPixel2    ;expand this
  893. z2:         dec     Counter
  894.             jnz     R1
  895.             jmp     Done
  896.  
  897. ;
  898. ; Plot the line.
  899. ;
  900.  
  901.         S3: mov     ax,si
  902.             shr     ax,1
  903.             mov     unk1,ax           ;unk1 = SI \ 2
  904.             mov     Counter,si
  905.  
  906.             ror     DPattern,1
  907.             jnc     z3
  908.             call    GPixel2    ;no reason to expand this.
  909. z3:         cmp     si,0
  910.             je      Done
  911.  
  912.         R3: add     dx,SlopeV
  913.             add     unk1,di
  914.             cmp     unk1,si
  915.             jle     R4
  916.             sub     unk1,si
  917.             inc     cx
  918.         R4: ror     DPattern,1
  919.             jnc     z4
  920.             call    GPixel2  ;expand this
  921. z4:         dec     Counter
  922.             jnz     R3
  923.        done:     ret
  924.  
  925. SlopeV      DW   0
  926. unk1        DW   0
  927. Counter     DW   0
  928. DPattern    DW   0
  929.  
  930. DrawLine    endp                      ;End of routine.
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.             PUBLIC  SetPalette        ;Make this routine available to LINK.
  942.  
  943. SetPalette  proc    far               ;Beginning of routine.
  944.  
  945.             push    bp
  946.             mov     bp,sp
  947.  
  948.             push    [bp + 06]
  949.             call    StringAddress     ;No JCXZ--it's got to be a 768 byter.
  950.             xchg    si,ax
  951.             push    ds
  952.             mov     ds,dx             ;now at DS:SI
  953.  
  954.             mov     dx,03C8H
  955.             xor     ax,ax
  956.             cli                             ; critical section:  no ints
  957.             out     dx,al                   ; starting register
  958.             inc     dx                      ; set up to update colors
  959. mov cx,3*256    ;although this should be ok from above.
  960.             rep     outsb                   ; whap!  Zango!  They're updated!
  961.             sti                             ; end of critical section
  962.  
  963.             pop     ds
  964.  
  965.  
  966. ;To set a RGB sequence we concern ourselves with two ports.  Let's say we
  967. ;want to change color #209 to the RGB values of (20h,40h,60h).  First we
  968. ;send the number of the color we want to alter out port #03C8:
  969. ;
  970. ;        Port [$03C8] := 209
  971. ;
  972. ;Next, we send the RGB values we want to change to out through port #03C9:
  973. ;
  974. ;        Port [$03C9] := $20;
  975. ;        Port [$03C9] := $40;
  976. ;        Port [$03C9] := $60;
  977. ;
  978. ;After we update each red, green, and blue value, port $3C8 advances to
  979. ;the next color number and we could do that one right away.  I can't
  980. ;begin to tell you how much faster this is than using the BIOS routines
  981. ;to do the same thing.  It was pretty painless also.
  982. ;
  983. ;There is one thing to consider.  While our palette is 6-6-6, the PCX
  984. ;format saves its palette as 8-8-8.  This means that White, for example,
  985. ;is stored as ($FF,$FF,$FF), while we need it as ($63,$63,$63).  This is
  986. ;very simple to fix.  Simply read in the palette, and as each byte comes
  987. ;in shift it two places to the right.
  988. ;
  989. ;So much for writing a palette register.  Reading the RGB values for a
  990. ;color register is just as simple.  the only difference is the first port
  991. ;we call is $3C7:
  992.  
  993.       Done: pop     bp
  994.             ret     2                 ;Pop-return past our input parameter.
  995.  
  996. SetPalette  endp                      ;End of routine.
  997.  
  998.  
  999.  
  1000. ;pass it a string of 768 bytes.
  1001.  
  1002.             PUBLIC  GetPalette        ;Make this routine available to LINK.
  1003.  
  1004. GetPalette  proc    far               ;Beginning of routine.
  1005.  
  1006.             push    bp
  1007.             mov     bp,sp
  1008.  
  1009.             push    [bp + 06]
  1010.             call    StringAddress     ;No JCXZ--it's got to be a 768 byter.
  1011.             xchg    di,ax             ;at ES:DI
  1012.  
  1013.             mov     dx,03C7H
  1014.             xor     ax,ax
  1015.             cli                             ; critical section:  no ints
  1016.             out     dx,al
  1017.             inc     dx
  1018.             inc     dx                      ; We check port 03C9 for values.
  1019. mov cx,3*256
  1020.             rep     insb
  1021.             sti                             ; end of critical section
  1022.  
  1023. ;So much for writing a palette register.  Reading the RGB values for a
  1024. ;color register is just as simple.  the only difference is the first port
  1025. ;we call is $3C7:
  1026. ;
  1027. ;        Port [$03C7] := 209
  1028. ;        Red   := Port [$03C9];
  1029. ;        Green := Port [$03C9];
  1030. ;        Blue  := Port [$03C9];
  1031. ;
  1032. ;The rest of the routine stays the same.
  1033.  
  1034.       Done: pop     bp
  1035.             ret     2                 ;Pop-return past our input parameter.
  1036.  
  1037. GetPalette  endp                      ;End of routine.
  1038.  
  1039.  
  1040. ;Draw-A-Single-Color-Solid-Line-Fast
  1041. ;
  1042. ;Input:
  1043. ;  bl  color to use
  1044. ;  cx  starting horizontal coordinate (always less than or equal to di)
  1045. ;  dx  starting vertical coordinate 
  1046. ;  di  ending horizontal coordinate
  1047. ;  si  ending vertical coordinate
  1048. ;  assumes a RET after this call, so we don't care what we destory.
  1049. ;
  1050. ; The goal being to use memory coordinates instead of screen coordinates
  1051. ; to draw a line.
  1052. ;
  1053. DASCSLF     proc    near               ;Beginning of routine.
  1054.  
  1055.  
  1056.             mov     SlopeVz,1
  1057.  
  1058.             sub     si,dx
  1059.             cmp     si,0
  1060.             jge     S1
  1061.             neg     si
  1062.             mov     SlopeVz,-1
  1063.  
  1064.         S1: sub     di,cx
  1065.  
  1066.         S2: cmp     di,si
  1067.             jle     S3
  1068.  
  1069.             mov     ax,di
  1070.             shr     ax,1
  1071.             mov     unkz,ax           ;unkz = DI \ 2     growth rate.
  1072.             mov     Counterz,di
  1073.             call    GPixel2    ;no reason to expand this.
  1074. z1:         cmp     di,0
  1075.             je      Done
  1076.  
  1077.         R1: inc     cx
  1078.             add     unkz,si
  1079.             cmp     unkz,di
  1080.             jle     R2
  1081.             sub     unkz,di
  1082.             add     dx,SlopeVz
  1083. r2:         call    GPixel2   ;expand this
  1084. z2:         dec     Counterz
  1085.             jnz     R1
  1086.             jmp     Done
  1087.  
  1088.  
  1089.         S3: mov     ax,si
  1090.             shr     ax,1
  1091.             mov     unkz,ax           ;unkz = SI \ 2
  1092.             mov     Counterz,si
  1093.             call    GPixel2    ;no reason to expand this.
  1094. z3:         cmp     si,0
  1095.             je      Done
  1096.  
  1097.         R3: add     dx,SlopeVz
  1098.             add     unkz,di
  1099.             cmp     unkz,si
  1100.             jle     R4
  1101.             sub     unkz,si
  1102.             inc     cx
  1103. r4:         call    GPixel2   ;expand this
  1104. z4:         dec     Counterz
  1105.             jnz     R3
  1106.  
  1107. done:            ret
  1108.  
  1109. slopevz     DW   0
  1110. unkz        DW   0
  1111. Counterz    DW   0
  1112.  
  1113. DASCSLF     endp                      ;End of routine.
  1114.  
  1115. GScrMem     DW   0
  1116. GModeInUse  DB   0
  1117.  
  1118.  
  1119. End 
  1120.  
  1121.  
  1122.  
  1123.  
  1124.